<?php

Loader::using("underscore::core::exceptions::ObjectResolutionException");

/**
 * This is the base class for lazy loaders that normally serves as a 
 * bridge between the bussiness model and the module.
 *
 * @author Virtualidad
 */
abstract class AbstractLoader {

    /**
     *
     * @var array
     */
    private $loadedObjects = array();
    private $moduleName;
    private $app;
    /**
     *
     * @var Principal
     */
    private $currentUser;

    public function __get($name) {
        return $this->load($name);
    }
    
    /**
     * Implementor must find the given object, load and instantiate it.
     * 
     * @param string $className The name of the class of the object to be loaded.
     * 
     * @return mixed An instance of the given class name.
     */
    protected abstract function resolveObject($className);

    /**
     * <p>Loads an instance of the given class name. There will be one only instance
     * per class name.</p>
     * 
     * <p><strong>Note:</strong> This method is invoked when the <code>__get</code> 
     * magic function is used thus the following code snipsets: 
     * <code>$myLoader->load("MyClass")</code> and <code>$myLoader->MyClass</code> 
     * are equivalent.</p>
     * 
     * @param string $className The class name to be loaded.
     * @return mixed An instance of the given class name.
     */
    public function load($className) {

        if (!array_key_exists($className, $this->loadedObjects)) {
            $this->loadedObjects[$className] = $this->resolveObject($className);
        }

        return $this->loadedObjects[$className];
    }

    public function getModuleName() {
        return $this->moduleName;
    }

    public function setModuleName($moduleName) {
        $this->moduleName = $moduleName;
    }
    
    public function getApp() {
        return $this->app;
    }

    public function setApp($app) {
        $this->app = $app;
    }

    /**
     * Checks if the file exists in which case it includes it.
     * 
     * @param type $name
     * @param type $path 
     * 
     * @throws ObjectResolutionException If the file doesn't exist.
     */
    protected function checkFile($name, $path) {
        $requiredFile = $path . $name . ".php";
        if (!is_file($requiredFile)) {
            throw new ObjectResolutionException($name, $path);
        }else{
            require_once $requiredFile;
        }
    }

    /**
     *
     * @return Principal
     * @deprecated Use <code>ModuleContext::instance()->getUser()</code> instead.
     */
    public function getCurrentUser() {
        return $this->currentUser;
    }

    public function setCurrentUser(&$currentUser) {
        $this->currentUser = $currentUser;
    }
}

?>
